Amazon EMRのチュートリアルの進め方によってはAmazon S3のAccess Deniedエラーでステップが失敗する可能性がある
Amazon EMRのステップがAmazon S3のAccess Deniedエラーで失敗する
おのやんです。
みなさん。Amazon EMR(以下、EMR)触ってますか?私は初めてEMRに触ったときには、公式ドキュメントのチュートリアルを進めました。
こちらのチュートリアルですが、2024年2月時点では、IAMインスタンスプロファイルなどの設定がいくつかユーザーに委ねられています。
そのため、設定によってはチュートリアルで用いるサンプルプログラムが失敗するかもしれません。
実際に私もいくつかチュートリアルを進める上でハマったので、今回はそちらを紹介したいと思います。
EMRのチュートリアルについて
EMRは、ビッグデータ解析のためのクラスタープラットフォームです。Apache HadoopやApache Sparkなどのビッグデータフレームワークを使って、大量のデータを効率的に処理、分析することができます。
このEMRですが、公式からチュートリアルが用意されています。チュートリアルで紹介されている通りの手順でEMRを操作すれば、EMRクラスターの作成から簡易的なSparkアプリケーションの実行まで、いい感じに触れることができます。
はじめてEMRを使う方にとっては、チュートリアルをひととおり実践することで、アプリケーション実行までの手順をおおまかに確認できます。
具体的な手順としては以下のようになります。
- データ(
food_establishment_data.csv
)とアプリケーション(health_violations.py
)をS3に保存する - EMRクラスターを作成する
- ステップを送信して、S3上のデータとアプリケーションをEMRクラスターで処理する
実際に私もEMRのアプデートブログを執筆する際にチュートリアルを参考にしたので、よければご覧ください。
EMRのS3 Access Deniedエラーの詳細
このEMRチュートリアルですが、ある時にアプリケーションの実行に失敗しました。
実際にS3に保存されてあるログを確認すると、今回はS3 Access Deniedというエラーメッセージが表示されています。
Error Code: AccessDenied; Request ID: XXXX; S3 Extended Request ID: XXXX; Proxy: null), S3 Extended Request ID: XXXX
Caused by: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: XXXX; S3 Extended Request ID: XXXX; Proxy: null), S3 Extended Request ID: XXXX
エラー文にも書いてありまずが、どうやらEMRクラスターで実行したステップ上で、S3へのアクセスが拒否されているようです。
EMRのS3 Access Deniedエラーの原因
こちらのエラーの原因は、EC2 インスタンスプロファイルの設定ミスです。
このチュートリアルでは、S3バケットの構造は以下のようになっています。なお、今回使用する S3バケットの名前はs3-bucket-name
とします。
s3-bucket-name ├── health_violations.py ├── food_establishment_data.csv └── logs/
本来であれば、EMRクラスター内のEC2インスタンスは、s3-bucket-name
内の全オブジェクトにアクセスできる必要があります。
しかし、EMRクラスター作成時のEC2 インスタンスプロファイル設定画面では、s3-bucket-name/logs/
以下のオブジェクトのみ許可している状態でした。EMRクラスターを作成する際にEC2 インスタンスプロファイルを新規で作成する場合、「アカウント内の特定のS3バケットまたはプレフィックス」を選択すると、EMRクラスターログ格納先S3バケットがデフォルトで選択されます。この設定をそのまま使用したんですね。
自動で作成されたIAMポリシーでも、s3-bucket-name/logs/
以下のオブジェクトのみを許可していることが確認できます。なお、本来JSONファイルではコメントアウトは無効ですが、今回はわかりやすさを優先して便宜的に使用しています。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", ... ], "Resource": [ "arn:aws:s3:::s3-bucket-name/logs", # ここ "arn:aws:s3:::s3-bucket-name/logs/*" # ここ ] }, { "Effect": "Allow", "Action": [ "s3:GetBucketVersioning", ... ], "Resource": [ "arn:aws:s3:::s3-bucket-name/logs", # ここ "arn:aws:s3:::elasticmapreduce", "arn:aws:s3:::s3-bucket-name/logs/*", # ここ "arn:aws:s3:::elasticmapreduce/*", "arn:aws:s3:::*.elasticmapreduce/*" ] } ] }
そのため、EMRクラスターでのアプリケーション実行時に、food_establishment_data.csv
と
health_violations.py
へEC2インスタンスがアクセスできず、ステップが失敗したわけです。
EMRのS3 Access Deniedエラーの解決法
というわけで、こちらのエラーを修正する際には、アクセスしたいS3バケットをs3-bucket-name
に変更すればOKです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", ... ], "Resource": [ "arn:aws:s3:::s3-bucket-name", # 修正 "arn:aws:s3:::s3-bucket-name/*" # 修正 ] }, { "Effect": "Allow", "Action": [ "s3:GetBucketVersioning", ... ], "Resource": [ "arn:aws:s3:::s3-bucket-name", # 修正 "arn:aws:s3:::elasticmapreduce", "arn:aws:s3:::s3-bucket-name/*", # 修正 "arn:aws:s3:::elasticmapreduce/*", "arn:aws:s3:::*.elasticmapreduce/*" ] } ] }
EMRチュートリアルでは適切な設定が必要
EMRのチュートリアルではユーザー自身が適切に設定する項目があります。
ここの設定を間違えるとアプリケーションが失敗するので、正しい設定になっているか落ち着いて確認してみましょう。では!